package com.mxpio.erp.plan.controller;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.inventory.entity.SupplyChain;
import com.mxpio.erp.common.purchase.entity.Supply;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.workshop.service.ManufactureOrderService;
import com.mxpio.erp.common.workshop.service.OutsourceOrderService;
import com.mxpioframework.jpa.JpaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mxpio.erp.common.plan.entity.ManufacturePlan;
import com.mxpio.erp.common.plan.service.ManufacturePlanService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.query.Criteria;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "ManufacturePlanController", description = "制造计划接口")
@RestController
@RequestMapping("/erp/plan/pm/")
public class ManufacturePlanController {
	
	@Autowired
	private ManufacturePlanService manufacturePlanService;
	@Autowired
	private ManufactureOrderService manufactureOrderService;
	@Autowired
	private OutsourceOrderService outsourceOrderService;
	@GetMapping("list")
	@Operation(summary = "制造计划列表", description = "获取制造计划列表（无分页）", method = "GET")
	public Result<List<ManufacturePlan>> list(@Parameter(description = "查询参数") Criteria criteria)
			throws UnsupportedEncodingException {
		List<ManufacturePlan> manufacturePlan = manufacturePlanService.list(ManufacturePlan.class, criteria);
		return Result.OK(manufacturePlan);
	}

	@GetMapping("page")
	@Operation(summary = "制造计划列表", description = "获取制造计划列表（分页）", method = "GET")
	@Transactional
	public Result<Page<ManufacturePlan>> page(@Parameter(description = "查询参数") Criteria criteria,
			@Parameter(description = "每页条数") Integer pageSize, 
			@Parameter(description = "页号") Integer pageNo)
			throws UnsupportedEncodingException {
		Pageable page = PageRequest.of(pageNo - 1, pageSize);
		Page<ManufacturePlan> manufacturePlan = manufacturePlanService.listPage( page, criteria);
		if (!manufacturePlan.getContent().isEmpty()){
			Set<String> itemCodes = JpaUtil.collect(manufacturePlan.getContent(), "itemCode");
			List<SupplyChain> chainsList = JpaUtil.linq(SupplyChain.class)
					.collect("pnCode", Supply.class,"pnCode")
					.equal("defaultSupply", CommonEnums.YesNo.YES.getCode()).in("itemCode", itemCodes).list();
			Map<String, List<SupplyChain>> scMap = chainsList.stream().collect(Collectors.groupingBy(SupplyChain::getItemCode));

			for (ManufacturePlan plan:manufacturePlan){
				if (plan.getItem()!=null){
					Item item = plan.getItem();
					plan.setManufactureAble(item.getManufactureAble());
					plan.setOutsourceAble(item.getOutsourceAble());//处理临时字段
					if (scMap.containsKey(item.getItemCode())){
						List<SupplyChain> supplyChains = scMap.get(item.getItemCode());
						if (!supplyChains.isEmpty()){
							Supply supply = supplyChains.get(0).getSupply();
							if (supply!=null){
								plan.setPnCode(supply.getPnCode());
								plan.setPnName(supply.getPnName());
							}
						}
					}
				}
			}
		}
		return Result.OK(manufacturePlan);
	}

	@GetMapping("list/{planNo}")
	@Operation(summary = "根据planNo获取制造计划", description = "根据planNo获取制造计划", method = "GET")
	public Result<ManufacturePlan> getById(
			@Parameter(description = "计划单号") @PathVariable(name = "planNo", required = true) String planNo) {
		ManufacturePlan manufacturePlan = manufacturePlanService.getById(ManufacturePlan.class, planNo);
		return Result.OK(manufacturePlan);
	}

	@RequestMapping("save")
	@Operation(summary = "保存制造计划", description = "保存制造计划")
	public Result<ManufacturePlan> save(@RequestBody ManufacturePlan manufacturePlan) {
		manufacturePlanService.save(manufacturePlan);
		return Result.OK(manufacturePlan);
	}

	@DeleteMapping("remove/{planNos}")
	@Operation(summary = "根据planNo删除制造计划", description = "删除制造计划", method = "DELETE")
	@Transactional(readOnly = false)
	public Result<ManufacturePlan> remove(
			@Parameter(description = "计划单号，多个单号用英文逗号分隔") @PathVariable(name = "planNos", required = true) String planNos) {
		String[] planNo = planNos.split(",");
		for (String key : planNo) {
			manufacturePlanService.delete(ManufacturePlan.class, key);
		}
		return Result.OK();
	}

	@RequestMapping("convert")
	@Operation(summary = "制造计划转生产订单", description = "制造计划转生产订单")
	public Result<Object> convert(@RequestBody List<ManufacturePlan> planList) {
		return manufactureOrderService.convertMOFromMPlan(planList);//调用具体实现来生成生产订单
	}

	@RequestMapping("entrust")
	@Operation(summary = "制造计划转委外计划", description = "制造计划转委外计划")
	public Result<Object> entrust(@RequestBody List<ManufacturePlan> planList) {
		return manufacturePlanService.changeToOutsourceFlag(planList);
	}

	@RequestMapping("convertoo")
	@Operation(summary = "委外计划转委外订单", description = "委外计划转委外订单")
	public Result<Object> convertoo(@RequestBody List<ManufacturePlan> planList) {
		return outsourceOrderService.convertOOFromMPlan(planList);//调用具体实现来生成生产订单
	}
	@GetMapping("split/{planNo}/{splitNum}")
	@Operation(summary = "拆分制造/委外计划", description = "拆分制造/委外计划", method = "GET")
	public Result<ManufacturePlan> spit(
			@Parameter(description = "计划单号") @PathVariable(name = "planNo", required = true) String planNo
			,@Parameter(description = "拆分数量") @PathVariable(name = "splitNum", required = true) BigDecimal splitNum) {
		return manufacturePlanService.split(planNo, splitNum);
	}
}
